package cn.vendgateway.com.filters;

import cn.vendcommon.com.entity.constants.CommonConstants;
import cn.vendcommon.com.entity.enums.CommonRedisKey;
import cn.vendgateway.com.properties.AuthProperties;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.net.InetSocketAddress;
import java.util.List;
import java.util.Objects;


@Component
@RequiredArgsConstructor  // 自动生成包含所有 final 字段和带有 @NonNull 注解字段的构造方法
public class AuthGlobalFilter implements GlobalFilter, Ordered {

    @Autowired
    private RedisTemplate redisTemplate;

    private final AuthProperties authProperties;
    private final AntPathMatcher antPathMatcher = new AntPathMatcher();

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest().mutate()
                .header(CommonConstants.REAL_IP, Objects.requireNonNull(exchange.getRequest().getRemoteAddress()).getHostString()) // 自定义头传递IP
                .header(CommonConstants.FEIGN_REQUEST_KEY,CommonConstants.FEIGN_REQUEST_FALSE)
                .build();
        // 延期处理
        return chain.filter(exchange.mutate().request(request).build()).then(Mono.fromRunnable(() -> {
            String token,redisKey;
            if(!StringUtils.isEmpty(token = exchange.getRequest().getHeaders().getFirst(CommonConstants.TOKEN_NAME))
                    && redisTemplate.hasKey(redisKey = CommonRedisKey.USER_TOKEN.getRealKey(token))){
                redisTemplate.expire(redisKey,CommonRedisKey.USER_TOKEN.getExpireTime(),CommonRedisKey.USER_TOKEN.getUnit());
            }
        }));
    }

//    @Override
//    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//        ServerHttpRequest request = exchange.getRequest();
//        // 放行注册、登录等无需认证的路径
//        if (isExclude(request.getPath().toString())) {
//            return chain.filter(exchange);
//        }
//        // 获取 Authorization 头
//        String token = null;
//        List<String> headers = request.getHeaders().get("Authorization");
//        if (headers != null && !headers.isEmpty()) {
//            token = headers.get(0);
//            if (token.startsWith("Bearer ")) {
//                token = token.substring(7);
//            }
//        }
//        ServerHttpResponse response = exchange.getResponse();
//        // JWT 校验
//        Map<String, Object> claims;
//        long userId;
//        try {
//            if (token == null || token.isEmpty()) {
//                // todo 加入自定义异常类
//                throw new Exception("缺少JWT令牌哦~");
//            }
//            claims = JwtUtil.parseToken(token);
//            userId = Long.parseLong(claims.get("id").toString());
//        } catch (Exception e) {
//            response.setStatusCode(HttpStatus.UNAUTHORIZED);
//            return response.setComplete(); // 直接返回 401
//        }
//
//        // 获取客户端 IP（注意可能有代理，需要考虑 X-Forwarded-For）
//        String clientIp = getClientIp(request);
//
//        // 将用户信息和 IP 传递给下游服务
//        ServerHttpRequest mutatedRequest = request.mutate()
//                .header(USER_INFO, Long.toString(userId))
//                .header(REAL_IP, clientIp)
//                .build();
//
//        ServerWebExchange mutatedExchange = exchange.mutate()
//                .request(mutatedRequest)
//                .build();
//
//        return chain.filter(mutatedExchange);
//    }

    // 判断是否为放行路径
    private boolean isExclude(String path) {
        for (String pattern : authProperties.getExcludePaths()) {
            if (antPathMatcher.match(pattern, path)) {
                return true;
            }
        }
        return false;
    }

    @Override
    public int getOrder() {
        return 0; // 越小优先级越高
    }

    /**
     * 获取客户端 IP 地址
     */
    private String getClientIp(ServerHttpRequest request) {
        // 优先从 X-Forwarded-For 里取（一般 nginx 会加上）
        List<String> forwardedValues = request.getHeaders().get("X-Forwarded-For");
        if (forwardedValues != null && !forwardedValues.isEmpty()) {
            return forwardedValues.get(0);
        }
        InetSocketAddress remoteAddress = request.getRemoteAddress();
        return remoteAddress != null ? remoteAddress.getAddress().getHostAddress() : "unknown";
    }
}
